package com.me.libgdx_test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;


//This class creates them main map that the character will be navigating
//Also stores the current coordinates of the player
public class ClassCreateDungeon {
	Random random = new Random(System.currentTimeMillis());
	private int[][] map;
	private int pStartX;
	private int pStartY;
	ClassCreateDungeon(Point Dim, boolean tutorial_map){
		//This ensures that the character does not start out on the edges of the map
		
		if(!tutorial_map){
			
			pStartX = random.nextInt( Dim.x-2 );
			pStartY = random.nextInt( Dim.y-2 );
			pStartX += 1;
			pStartY += 1;
			map = new int [Dim.x][Dim.y];
			
			int plot;
			List<coorObject> trail = new ArrayList<coorObject>();
			Integer[] direction = new Integer[]{0, 1, 2, 3};
			coorObject holder;
			
			for(int y = 0; y< Dim.y; y++){
				for (int x=0; x<Dim.x; x++){
					this.map[x][y]= 1;
				}
			}
			
			//This is the point where the player starts
			
			trail.add(new coorObject(pStartX, pStartY));
			
			//Uses kruskal's algorithm to generate a random navigable map
			while (!trail.isEmpty()){
				//Picks a random wall to branch the trail out at
				plot = random.nextInt( trail.size() );
				holder = trail.get(plot);
				this.map[holder.getX()][holder.getY()]= 0;
	
				// Shuffle the elements in the array
				//This is to make sure that the roads twist, and
				//are not straight corridors after generation
				Collections.shuffle(Arrays.asList(direction));
				//If this direction is in the map
				for (int road : direction){
					if (road == 0){
						if (holder.getX()-1 != 0)
						{
							//If the next cell over in the same direction is not in the maze
							if (checkWall(holder.getX()-2, holder.getY(), Dim)){
								//Mark the cell in between as a transition, and the next cell as part of maze 
								this.map[holder.getX()-1][holder.getY()]= 0;
								this.map[holder.getX()-2][holder.getY()]= 0;
								trail.add(new coorObject(holder.getX()-2, holder.getY()));
							}
						}
					}
					if (road == 1){
						if (holder.getY()+1 != Dim.y-1)
						{
							if (checkWall(holder.getX(), holder.getY()+2, Dim)){
								this.map[holder.getX()][holder.getY()+1]= 0;
								this.map[holder.getX()][holder.getY()+2]= 0;
								trail.add(new coorObject(holder.getX(), holder.getY()+2));
							}
						}
					}
					if (road == 2){
						if (holder.getX()+1 != Dim.x-1)
						{
							if (checkWall(holder.getX()+2, holder.getY(), Dim)){
								this.map[holder.getX()+1][holder.getY()]= 0;
								this.map[holder.getX()+2][holder.getY()]= 0;
								trail.add(new coorObject(holder.getX()+2, holder.getY()));
							}
						}
					}
					if (road == 3){
						if (holder.getY()-1 != 0)
						{
							if (checkWall(holder.getX(), holder.getY()-2, Dim)){
								this.map[holder.getX()][holder.getY()-1]= 0;
								this.map[holder.getX()][holder.getY()-2]= 0;
								trail.add(new coorObject(holder.getX(), holder.getY()-2));
							}
						}
					}
				}
				trail.remove(plot);
				
			}
			
			map[pStartX-1][pStartY-1] = 0;
			map[pStartX][pStartY-1] = 0;
			map[pStartX+1][pStartY-1] = 0;
			map[pStartX-1][pStartY] = 0;
			map[pStartX+1][pStartY] = 0;
			map[pStartX-1][pStartY+1] = 0;
			map[pStartX][pStartY+1] = 0;
			map[pStartX+1][pStartY+1] = 0;
			
			for(int i = 0; i < 10;){
				int selectorX = random.nextInt( Dim.x-2 );
				int selectorY = random.nextInt( Dim.y-2 );
				if (map[selectorX+1][selectorY+1] == 1){
					map[selectorX+1][selectorY+1] = 0;
					i++;
				}
			}
		
		}else{
			pStartX = 0;
			pStartY = 0;
			int[][] mapTemplate = {
					{0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0}, //0
					{0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0}, //1
					{0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0}, //2
					{1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0}, //3
					{0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0}, //4
					{0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0}, //5
					{0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,0,1}, //6
					{1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0}, //7
					{0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, //8
					{0,0,1,0,0,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1}, //9
					{0,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, //10
					{0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, //11
					{1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,1,1,0}, //12
					{0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0}, //13
					{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0}, //14
					{0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0}, //15
					{1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0}, //16
					{0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0}, //17
					{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0}, //18
					{0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0}  //19
			};    // 0.1.2.3.4.5.6.7.8.9.10111213141516171819
			map = new int [mapTemplate[0].length][mapTemplate.length];
			for(int y = 0; y< Dim.y; y++){
				for (int x=0; x<Dim.x; x++){
					this.map[x][y]= mapTemplate[x][y];
				}
			}
		}
		//for(int y=0;y<Dim;y++){
		//	for(int x=0;x<Dim;x++){
		//		int randomIndex = random.nextInt( 2 );
		//		this.map[x][y]= randomIndex;
		//	}
		//}
	}
	/*ClassCreateMap(boolean tutorial){
		int[][] mapTemplate = {
				{0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0}, //0
				{0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0}, //1
				{0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0}, //2
				{1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0}, //3
				{0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0}, //4
				{0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0}, //5
				{0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,0,1}, //6
				{1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0}, //7
				{0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, //8
				{0,0,1,0,0,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1}, //9
				{0,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, //10
				{0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, //11
				{1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,1,1,0}, //12
				{0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0}, //13
				{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0}, //14
				{0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0}, //15
				{1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0}, //16
				{0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0}, //17
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0}, //18
				{0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0}  //19
		};    // 0.1.2.3.4.5.6.7.8.9.10111213141516171819
		
		map = new int[20][20];
		for(int y = 0; y < 20; y++){
			for(int x = 0; x< 20; x++){
				map[y][x] = mapTemplate[x][y];
			}
		}
		
		pStartX = 1;
		pStartY = 1;
		
	}*/
	//This helps to keep track of the coordinates that are used
	//to make the path on the map
	private class coorObject {
		int x;
		int y;
		coorObject(int x, int y){
			this.x = x;
			this.y = y;
		}
		int getX(){
			return x;
		}
		int getY(){
			return y;
		}
	}
	public boolean checkWall(int X, int Y, Point Dim){
		if ((X >= 0) && (Y >= 0) && (X<Dim.x) && (Y<Dim.y)){
			if (map[X][Y]== 1){
			//The next cell over is not a path nor outside of the map
				return true;
			}
		}
		return false;
	}
	public Point getPlayer(){return new Point(pStartX,pStartY);}
	public void setPlayer(Point p){pStartX = p.x;pStartY = p.y;}
	public int returnMapValue(Point p){return map[p.x][p.y];}
	public int[][] getMap(){return map;}
}
